home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / STUTTGART / LANG / PROLOG / HUMBOLT / HUMBOLTS / _files / _humboltsr / ATOMS._c < prev    next >
Text File  |  1990-10-04  |  35KB  |  922 lines

  1. /***************************************************
  2. ****************************************************
  3. **                                                **
  4. **  HU-Prolog     Portable Interpreter System     **
  5. **                                                **
  6. **  Release 1.62   January  1990                  **
  7. **                                                **
  8. **  Authors:      C.Horn, M.Dziadzka, M.Horn      **
  9. **                                                **
  10. **  (C) 1989      Humboldt-University             **
  11. **                Department of Mathematics       **
  12. **                GDR 1086 Berlin, P.O.Box 1297   **
  13. **                                                **
  14. ****************************************************
  15. ***************************************************/
  16.  
  17. #include "systems.h"
  18. #include "types.h"
  19. #include "errors.h"
  20. #include "atoms.h"
  21. #include "manager.h"
  22.  
  23. /*
  24. ATOM TABLE
  25. Each atom is associated with operator and clause information which is
  26. stored in an 'atomentry'.  The identifiers for atoms in the input are
  27. mapped to the corresponding entry through a hash table.  Collisions are
  28. handled by chaining together atom entries. 
  29. */
  30.  
  31. IMPORT ATOM BASEATOM,ATOMSTOP,ATOMHTOP;
  32. IMPORT STRING STRINGSTOP; 
  33. IMPORT TERM BASETERM,GLOTOP;
  34. IMPORT void ARGERROR(),ERROR(),ABORT();
  35. IMPORT TERM A0,A1,A2;
  36. IMPORT string strcat();                  /* from CLIB */
  37. IMPORT boolean WARNFLAG;       /* from prolog.c        */
  38. IMPORT boolean aSYSMODE;
  39. IMPORT ATOM heapatom(),stackatom();
  40. IMPORT STRING heapstring(),stackstring();
  41. IMPORT int INTVALUE();
  42. IMPORT void TESTATOM();
  43. IMPORT boolean UNIFY();
  44. IMPORT void wq();
  45. IMPORT void CHECKATOM();
  46.  
  47. /*
  48. EXPORT   ATOM LOOKUP(string,int,boolean);
  49. EXPORT   ATOM LOOKATOM(ATOM,int);
  50. EXPORT   ATOM atom(TERM),copyatom(ATOM),GetAtom(ATOM);
  51. EXPORT   TERM LISTREP(string);
  52. EXPORT   string NEWATOM;
  53. EXPORT  void STARTATOM(),ATOMCHAR();
  54. EXPORT   InitAtoms();
  55. EXPORT  void DOOP();
  56. EXPORT   ATOM LASTATOM;
  57. EXPORT   void InitUAtom();
  58. */
  59.  
  60.  
  61. GLOBAL ATOM LASTATOM=LAST_ATOM;
  62.  
  63. #define HASHSIZE 0x100
  64. GLOBAL ATOM  HASHTAB [HASHSIZE+1];
  65. GLOBAL int HASH_SIZE=HASHSIZE; /* for save.c */
  66.  
  67. #define hashcode(C1,C2)     ((((C1) & 0x7f)<<1)|     \
  68.                 ((((C1)?(C2):0)&0x40)>>6))
  69. #define strhash(S)     hashcode(*S,*(S+1))
  70. LOCAL int idhash(ATOM A)
  71. { register STRING index; index=longstring(A);
  72.   return hashcode(repchar(index),repchar(index+1));
  73. }
  74.  
  75. /* create an new atom */
  76.  
  77. #if !BIT8
  78. #define STRINGSPACE 256 /* Size of string buffer. */
  79. #endif
  80. #if BIT8
  81. #define STRINGSPACE 128 /* Size of string buffer. */
  82. #endif
  83.  
  84. GLOBAL char stab[STRINGSPACE]; /* also used in help.c */
  85.  
  86. string NEWATOM=stab;
  87. LOCAL int NEWINDEX;
  88.  
  89. GLOBAL void STARTATOM (void)
  90. { NEWATOM=stab; NEWINDEX=0; }
  91.  
  92. GLOBAL void ATOMCHAR (register char C)
  93. { if(NEWINDEX>=STRINGSPACE) ERROR(aSTRINGSPACEE);
  94.   stab[NEWINDEX++]=C;
  95. }
  96.  
  97. /* #if !POINTEROFFSET */
  98. LOCAL int idstrcmp(ATOM A, register string S)
  99. { register STRING index;
  100.   index=longstring(A);
  101.   while(*S==repchar(index)) {if(*S++) index++; else return 0;}
  102.   return (repchar(index) - *S);
  103. }
  104. /* #endif
  105. #if POINTEROFFSET
  106. #define idstrcmp(A,s)   strcmp(longstring(A),s)
  107. #endif
  108. */
  109. LOCAL ATOM CONSTATOM;  /* used during initialization only */
  110. LOCAL boolean INIT;
  111.  
  112. LOCAL void initfields(register ATOM A, register int AR)
  113. {
  114.       info(A)=0;
  115.       oprec(A)=0; 
  116.       clause(A)=nil_clause;
  117.       arity(A)=AR;
  118.       nextatom(A)=chainatom(A)=nil_atom;
  119. }
  120.  
  121. /* Enter an atom and return its value. */
  122. GLOBAL ATOM LOOKUP (string str, int ar, boolean heap)
  123. /*  search and create only in heap */
  124.     register ATOM A,OA;
  125.     ATOM NA,CHAINATOM,HASHATOM;
  126.     int cmp,H,nf;
  127.     boolean create;
  128.  
  129. /*****************************************/
  130. /*    heap=true; */
  131. /*****************************************/
  132.     OA=NA=CHAINATOM=nil_atom;
  133.     nf=0;
  134.     H=strhash(str);
  135. #if DEBUG
  136.     if(DEBUGFLAG) 
  137.     { out_1("\nLOOKUP:");out_1(str);out_1("/");out_1(itoa(ar));
  138.       out_1(heap ? " heap " : " stack ");
  139.       out_1("hash:");out_1(itoa(H));out_1(";");out_1(itoa(HASHTAB[H]));
  140.     }
  141. #endif
  142.     if(ar < 0 ) { ar= -ar; create=false;} else create=true;
  143.     if(ar > MAXARITY) ERROR(BADARITYE);
  144.     HASHATOM=HASHTAB[ H ];
  145.     if(HASHATOM) /* search in primary chain */
  146.     {
  147. #if DEBUG
  148.     if(DEBUGFLAG) 
  149.         { out_1("#"); }
  150. #endif
  151.         OA=A=HASHATOM;
  152.         while(non_nil_atom(A) && (cmp=idstrcmp(A,str)) < 0)
  153.         {OA=A;A=nextatom(A);nf++;}
  154.         if(A && cmp==0) NA=A;
  155.         while(non_nil_atom(A) && (cmp=idstrcmp(A,str))==0 && 
  156.       (hide(A) || private(A)))
  157.         {
  158. #if DEBUG
  159.             if(DEBUGFLAG)
  160.             {
  161.                 out_1("{");
  162.                 out_1(itoa(A));
  163.                 if(A)
  164.                 {
  165.                     out_1(";");out_1(itoa(cmp));
  166.                     out_1(";");out_1(itoa(hide(A)));
  167.                     out_1(";");out_1(itoa(private(A)));
  168.                     out_1(";");out_1(itoa(nextatom(A)));
  169.  
  170.                 }
  171.                 out_1("}");
  172.             }
  173. #endif
  174.             OA=A;A=nextatom(A);nf++;
  175.         }
  176.         if(!A) cmp=1;
  177.         if(A && cmp==0) /* search in secondary chain */
  178.         {
  179.         int AA,OAA;
  180. #if DEBUG
  181.             if(DEBUGFLAG) out_1("@");
  182. #endif
  183.             nf++;
  184.             CHAINATOM=NA=OA=A;
  185.         AA=OAA=arity(A);
  186.             while(non_nil_atom(A) && !(ar==AA ||
  187.                          (ar < AA && ar > OAA) ||
  188.                          (ar < AA && OAA > AA)
  189.                         ))
  190.             { OA=A; OAA=AA; A=chainatom(A); AA=arity(A);}
  191.             if( A && ar==AA) goto found;
  192.         }
  193.     }
  194.     if(!heap)  /* search atom in stack */
  195.     {
  196.         for(A=ATOMSTOP;A<MAXATOMS;inc_atom(A))
  197.             if(idstrcmp(A,str)==0)
  198.             { NA=A; if(ar==arity(A))goto found; }
  199.     }
  200.     if(create) /* create atom */
  201.     {
  202.         if(INIT) A=CONSTATOM;
  203.         else if(heap) A=heapatom();
  204.         else { STRINGSTOP=(STRING)nextatom(ATOMSTOP); A=stackatom(); }
  205.         if( NA ) longstring(A)=longstring(NA);
  206.         else if(heap) longstring(A)=heapstring(str);
  207.         else longstring(A)=stackstring(str); 
  208.         initfields(A,ar);
  209.         setfirst(A);
  210.         if(heap) 
  211.         {
  212.             if(HASHATOM==nil_atom || nf==0 )
  213.             {
  214.                 nextatom(A)=HASHTAB[H];
  215.                 HASHTAB[H]=A;goto found;
  216.             }
  217.             if(cmp !=0)  
  218.             {
  219.                 nextatom(A)=nextatom(OA);
  220.                 nextatom(OA)=A;
  221.             }
  222.             else
  223.             {
  224.                 setnotfirst(A);
  225.                 chainatom(A)=chainatom(OA);
  226.                 nextatom(A)=CHAINATOM;
  227.                 chainatom(OA)=A;
  228.                 
  229.             }
  230.         }
  231.         else
  232.             nextatom(A)= (card)STRINGSTOP;
  233.     }
  234.     else A=nil_atom;
  235.   found:
  236.     STARTATOM();
  237. #if DEBUG
  238.     if(DEBUGFLAG){ out_1(itoa(A));out_1("\n");}
  239. #endif
  240.     return A;
  241. }
  242.  
  243. LOCAL char tempstring[STRINGSPACE];
  244.  
  245. #if !POINTEROFFSET
  246. GLOBAL string tempcopy(ATOM A)
  247. { register int si; 
  248.   register STRING i;
  249.   register char CH; 
  250.   i=longstring(A); 
  251.   for(CH=repchar(i),si=0;tempstring[si++]=CH;CH=repchar(++i))
  252.      if(si>=STRINGSPACE) ERROR(ATOMSPACEE);
  253.   return tempstring;
  254. }
  255. #endif
  256.  
  257. GLOBAL ATOM modify(ATOM A)
  258. { register int si; 
  259.   register STRING i;
  260.   register char CH; 
  261.   i=longstring(A); 
  262.   for(CH=repchar(i),si=0;tempstring[si++]=CH;CH=repchar(++i))
  263.      if(si+1>=STRINGSPACE) ERROR(ATOMSPACEE);
  264.   si--; tempstring[si++]='_'; tempstring[si++]=0;
  265.   return LOOKUP(tempstring,arity(A),true);
  266. }
  267.  
  268. GLOBAL ATOM LOOKATOM(register ATOM A, register int ar)
  269. {
  270.     register ATOM OA;
  271.     ATOM AA;
  272.     boolean create;
  273.     boolean heap=false;
  274.     if(ar < 0 ) { ar= -ar; create=false;} else create=true;
  275.     if(ar > MAXARITY) ERROR(BADARITYE);
  276.     AA=A;
  277. #if DEBUG
  278.     if(DEBUGFLAG)
  279.     {
  280.         out_1("\nLOOKATOM:("),out_1(tempcopy(A)),
  281.         out_1(","),out_1(itoa(A)),out_1(","),out_1(itoa(ar));
  282.         out_1(")");
  283.     }
  284. #endif
  285.     if(A <=ATOMHTOP) /* A is an heapatom */
  286.     {
  287.         if(arity(A)==ar) return A;
  288.         if(private(A) || hide(A)) heap=true;
  289. #if DEBUG
  290.         if(DEBUGFLAG) { out_1(heap ? "<heap>" : "<stack>"); }
  291. #endif
  292.         if(!first(A)) A=nextatom(A);
  293.         OA=A;
  294.         while(non_nil_atom(A) && !(ar==arity(A) ||
  295.                      (ar < arity(A) && ar > arity(OA)) ||
  296.                      (ar < arity(A) && arity(OA) > arity(A))
  297.                     ))
  298.         { OA=A;A=chainatom(A);
  299.         }
  300.         if(A && arity(A)==ar) 
  301.         {
  302. #if DEBUG
  303.         if(DEBUGFLAG) { out_1("<found:");out_1(itoa(A));out_1(">"); }
  304. #endif
  305.             return A;
  306.         }
  307.         if(heap)
  308.             if(create)
  309.             {
  310.                 A=heapatom();
  311.                 longstring(A)=longstring(OA);
  312.                 initfields(A,ar);
  313.                 chainatom(A)=chainatom(OA);
  314.                 chainatom(OA)=A;
  315.                 nextatom(A)=  (first(OA) ? OA : nextatom(OA));
  316.                 if(private(OA))setprivate(A);
  317.                 if(hide(OA))sethide(A);
  318. #if DEBUG
  319.         if(DEBUGFLAG) { out_1("<create:");out_1(itoa(A));out_1(">"); }
  320. #endif
  321.                 return A;
  322.             }
  323.             else return nil_atom;
  324.     }
  325. #if DEBUG
  326.         if(DEBUGFLAG) { out_1("<call LOOKUP>"); }
  327. #endif
  328.     return LOOKUP(tempcopy(AA),(create ? ar : -ar),heap);
  329. }
  330.  
  331. GLOBAL ATOM atom(register TERM X)
  332.   if(name(X)!=DIVIDE_2) ARGERROR();
  333.   return LOOKATOM(name(arg1(X)),INTVALUE(arg2(X)));
  334. }
  335.  
  336. GLOBAL ATOM copyatom(register ATOM A)
  337. /* copy an Atom A to the heap */
  338. {
  339.     register ATOM NA;
  340.     register TERM T;
  341.     if(A <=  ATOMHTOP) return(A); /* do nothing */
  342.     NA=LOOKUP(tempcopy(A),(int)arity(A),true);
  343.     for(T=BASETERM;T<=GLOTOP;inc_term(T))
  344.       {  if(name(T)==A) name(T)=NA; }
  345.     setrc(NA); /* for reconsult */
  346.     return NA;
  347. }
  348.  
  349.  
  350. LOCAL void PRIVATE(register ATOM A)
  351. {
  352.     A=copyatom(A);
  353.     if(!first(A)) A=nextatom(A);
  354.     while(non_nil_atom(A)) { setprivate(A); A=chainatom(A); }
  355.     return;
  356. }
  357.     
  358. LOCAL void HIDE(register ATOM A)
  359. {
  360.     register string str;
  361.     register int cmp;
  362.     ATOM AA=nil_atom;
  363.     A=copyatom(A);
  364.     str=tempcopy(A);
  365.     if(!first(A)) A=nextatom(A);
  366.     while(non_nil_atom(A)) { sethide(A); A=chainatom(A); }
  367.     A=HASHTAB[strhash(str)];
  368.     while(non_nil_atom(A) && (cmp=idstrcmp(A,str)) <=0 )
  369.     {
  370.         if(cmp==0 && !hide(A) && private(A)) AA=A;
  371.         A=nextatom(A);
  372.     }
  373.     while(non_nil_atom(AA)) { setnotprivate(AA); AA=chainatom(AA); }
  374. }
  375.  
  376. GLOBAL void DOPRIVATE(void)
  377. { while(name(A0)==CONS_2)
  378.     { PRIVATE(name(arg1(A0))); A0=arg2(A0); }
  379.   if(name(A0) !=NIL_0) PRIVATE(name(A0));
  380. }
  381.  
  382. GLOBAL void DOHIDE(void)
  383.   while(name(A0)==CONS_2)
  384.     { HIDE(name(arg1(A0))); A0=arg2(A0); }
  385.   if(name(A0) !=NIL_0) HIDE(name(A0));
  386. }
  387.  
  388. /* A Prolog list of the characters of s: cf. 'atom'. */
  389. GLOBAL TERM LISTREP (register string S)
  390. { register TERM  X;
  391.   register int  N, LENGTH;
  392.   LENGTH=0;
  393.   while(S[LENGTH]) LENGTH++;
  394.   if(LENGTH==0) return mkatom(NIL_0);
  395.   X=mk2sons(INTT,(TERM)S[N=LENGTH-1],NIL_0,nil_term);
  396.   while(--N >=0)
  397.       X=mk2sons(INTT,(TERM)S[N],CONS_2,X);
  398.   return mkfunc(CONS_2,X);
  399. }
  400.  
  401. #define nextchain(A) (first(A) ?  nextatom(A) : nextatom(nextatom(A)))
  402. GLOBAL ATOM GetAtom(register ATOM A)
  403. {
  404.     register int count;
  405.   start:;
  406.     if(A==nil_atom) count=0;
  407.     else if(chainatom(A)) {A=chainatom(A); goto found;}
  408.     else if(nextchain(A)) 
  409.         {A=  nextchain(A);goto found;}
  410.     else count=idhash(A)+1;
  411.     while(count < HASHSIZE && HASHTAB[count]==nil_atom) count++;
  412.     if(count < HASHSIZE) A=HASHTAB[count]; 
  413.     else A=nil_atom;
  414.   found:;
  415.     if(non_nil_atom(A) && ( private(A) || hide(A))) 
  416.       goto start;
  417.     return A;
  418. }
  419.  
  420.  
  421. /************ I N I T I A L I S A T I O N ***************/
  422.  
  423. #define sysflag 0x4000
  424.  
  425. LOCAL struct { ATOM macro;
  426.   string str;
  427.   char predtype;
  428.   char optype;
  429.   PREC_TYPE  prec;
  430.        } 
  431.        
  432. InitT[] 
  433. ={
  434. #if LONGARITH
  435.     { LONGT       , "<<LONG>>"  , NORMP   , NONO , LONGSIZE       },
  436. #endif
  437. #if REALARITH 
  438.     { REALT       , "<<REAL>>"  , NORMP   , NONO , REALSIZE       },
  439. #endif
  440.     { READ_1      , "read"      , EVALP   , NONO , 1    |sysflag  },
  441.     { READ_2      , "read"      , EVALP   , NONO , 2    |sysflag  },
  442.     { WRITE_1     , "write"     , EVALP   , NONO , 1    |sysflag  },
  443.     { WRITEQ_1    , "writeq"    , EVALP   , NONO , 1    |sysflag  },
  444.     { DISPLAY_1   , "display"   , EVALP   , NONO , 1    |sysflag  },
  445.     { GET0_1      , "get0"      , EVALP   , NONO , 1    |sysflag  },
  446.     { UNGET_0     , "unget"     , EVALP   , NONO , 0    |sysflag  },
  447.     { GET_1       , "get"       , EVALP   , NONO , 1    |sysflag  },
  448.     { SKIP_1      , "skip"      , EVALP   , NONO , 1    |sysflag  },
  449.     { ASK_1       , "ask"       , EVALP   , NONO , 1    |sysflag  },
  450.     { PUT_1       , "put"       , EVALP   , NONO , 1    |sysflag  },
  451.     { CLS_0       , "cls"       , EVALP   , NONO , 0    |sysflag  },
  452.     { GOTOXY_2    , "gotoxy"    , EVALP   , NONO , 2    |sysflag  },
  453.     { EOLN_0      , "eoln"      , EVALP   , NONO , 0    |sysflag  },
  454.     { EOF_0       , "eof"       , EVALP   , NONO , 0    |sysflag  },
  455.     { NL_0        , "nl"        , EVALP   , NONO , 0    |sysflag  },
  456.     { TAB_1       , "tab"       , EVALP   , NONO , 1    |sysflag  },
  457.     { FILEE_0     , "fileerrors", EVALP   , NONO , 0    |sysflag  },
  458.     { FILEE_1     , "fileerrors", EVALP   , NONO , 1    |sysflag  },
  459.     { NFILEE_0    , "nofileerrors",EVALP  , NONO , 0    |sysflag  },
  460. #ifdef ARCHY
  461.     { SYNCLOSE_0  , "syneclose",  EVALP   , NONO , 0    |sysflag  }, 
  462.     { NSYNCLOSE_0 , "nosyneclose",EVALP   , NONO , 0    |sysflag  },
  463. #endif
  464.     { SEE_1       , "see"       , EVALP   , NONO , 1    |sysflag  },
  465.     { SEEING_1    , "seeing"    , EVALP   , NONO , 1    |sysflag  },
  466.     { SEEN_0      , "seen"      , EVALP   , NONO , 0    |sysflag  },
  467.     { TELL_1      , "tell"      , EVALP   , NONO , 1    |sysflag  },
  468.     { TELLING_1   , "telling"   , EVALP   , NONO , 1    |sysflag  },
  469.     { TOLD_0      , "told"      , EVALP   , NONO , 0    |sysflag  },
  470.     { OPEN_1      , "open"      , EVALP   , NONO , 1    |sysflag  },
  471.     { CLOSE_1     , "close"     , EVALP   , NONO , 1    |sysflag  },
  472.     { SEEK_2       , "seek"      , EVALP   , NONO , 2    |sysflag  },
  473.  
  474.     { TTYGET_1     , "ttyget"    , EVALP   , NONO , 1    |sysflag  },
  475.     { TTYPUT_1     , "ttyput"    , EVALP   , NONO , 1    |sysflag  },
  476.     { TTYGET0_1    , "ttyget0"   , EVALP   , NONO , 1    |sysflag  },
  477.     { TTYREAD_1    , "ttyread"   , EVALP   , NONO , 1    |sysflag  },
  478.     { TTYWRITE_1  , "ttywrite"   , EVALP   , NONO , 1    |sysflag  },
  479.     { TTYSKIP_1    , "ttyskip"   , EVALP   , NONO , 1    |sysflag  },
  480.     { TTYCLS_0     , "ttycls"    , EVALP   , NONO , 0    |sysflag  },
  481.     { TTYGOTOXY_2 , "ttygotoxy"  , EVALP   , NONO , 2    |sysflag  },
  482.     { TTYTAB_1     , "ttytab"    , EVALP   , NONO , 1    |sysflag  },
  483.     { TTYASK_1     , "ttyask"    , EVALP   , NONO , 1    |sysflag  },
  484.     { TTYNL_0      , "ttynl"     , EVALP   , NONO , 0    |sysflag  },
  485.  
  486.     { FNAME_2     , "$file"      , NORMP  , NONO , 2     |sysflag  },
  487.     { FASSIGN_2   , "assign"     , EVALP  , NONO , 2     |sysflag  },
  488.     { aWINDOW_0   , "window"     , EVALP  , NONO , 0     |sysflag  },
  489.     { WGET0_1     , "wget0"      , EVALP  , NONO , 1     |sysflag  },
  490.  
  491. #if WINDOWS
  492.     { BLINK_0     , "blink"      , NORMP  , NONO , 0               },
  493.     { REVERSE_0   , "reverse"    , NORMP  , NONO , 0               },
  494.     { BOLD_0      , "bold"       , NORMP  , NONO , 0               },
  495.     { UNDER_0     , "underline"  , NORMP  , NONO , 0               },
  496.     { WINDOW_6    , "window"     , NORMP  , NONO , 6               },
  497. #endif
  498.  
  499.  
  500.     { TRACE_0     , "trace"     , EVALP   , NONO , 0    |sysflag  },
  501.     { TRACE_1     , "trace"     , EVALP   , NONO , 1    |sysflag  },
  502.     { NOTRACE_0   , "notrace"   , EVALP   , NONO , 0    |sysflag  },
  503.     { ECHO_1      , "echo"      , EVALP   , NONO , 1    |sysflag  },
  504.     { WARN_1      , "warn"      , EVALP   , NONO , 1    |sysflag  },
  505.     { DEBUG_1     , "$debug"    , EVALP   , NONO , 1    |sysflag  },
  506.     { OCHECK_1    , "ocheck"    , EVALP   , NONO , 1    |sysflag  },
  507.     { SPY_1       , "spy"       , EVALP   , NONO , 1    |sysflag  },
  508.     { NOSPY_1     , "nospy"     , EVALP   , NONO , 1    |sysflag  },
  509.     { SYSMODE_1   , "sysmode"   , EVALP   , NONO , 1    |sysflag  },
  510.     { aINTERRUPT_1, "interrupt" , EVALP   , NONO , 1    |sysflag  },
  511.     { REDUCE_1    , "reducing"  , EVALP   , NONO , 1    |sysflag  },
  512.  
  513.     { ATOM_1      , "atom"      , ISATOMP , NONO , 1    |sysflag  },
  514.     { CURATOM_1   , "current_atom",BTEVALP, NONO , 1    |sysflag  },
  515.     { CUROP_3     , "current_op", BTEVALP , NONO , 3    |sysflag  },
  516.     { CURPRED_1   , "current_predicate",BTEVALP,NONO,1    |sysflag  },
  517.     { INTEGER_1   , "integer"   , ISINTEGERP,NONO, 1    |sysflag  },
  518.     { NUMBER_1    , "number"    , EVALP   , NONO , 1    |sysflag  },
  519.     { ATOMIC_1    , "atomic"    , EVALP   , NONO , 1    |sysflag  },
  520.     { LIST_1      , "list"      , EVALP   , NONO , 1    |sysflag  },
  521.     { MEMBER_2    , "member"    , BTEVALP , NONO , 2    |sysflag  },
  522.     { IS_MEMBER_2 , "memberchk" , ISMEMBP , NONO , 2    |sysflag  },
  523.     { NO_MEMBER_2 , "nonmember" , NOMEMBP , NONO , 2    |sysflag  },
  524.     { APP_3       , "sysappend" , EVALP   , NONO , 3    |sysflag  },
  525.     { COMPOUND_1  , "compound"  , EVALP   , NONO , 1    |sysflag  },
  526.     { STRING_1    , "string"    , EVALP   , NONO , 1    |sysflag  },
  527.     { VAR_1       , "var"       , ISVARP  , NONO , 1    |sysflag  },
  528.     { NONVAR_1    , "nonvar"    , EVALP   , NONO , 1    |sysflag  },
  529.     { INVAR_1     , "invar"     , EVALP   , NONO , 1    |sysflag  },
  530.     { GROUND_1    , "ground"    , EVALP   , NONO , 1    |sysflag  },
  531.     { FUNCTOR_3   , "functor"   , EVALP   , NONO , 3    |sysflag  },
  532.     { ARG_3       , "arg"       , EVALP   , NONO , 3    |sysflag  },
  533.     { NAME_2      , "name"      , EVALP   , NONO , 2    |sysflag  },
  534.     { UNIV_2      , "=.."       , EVALP   , XFXO , 700  |sysflag  },
  535.  
  536.     { DBREF_1     , "_db_ref"   , NORMP   , NONO , 1              },
  537.     { ASSERT_1    , "assert"    , EVALP   , NONO , 1    |sysflag  },
  538.     { ASSERTA_1   , "asserta"   , EVALP   , NONO , 1    |sysflag  },
  539.     { ASSERTZ_1   , "assertz"   , EVALP   , NONO , 1    |sysflag  },
  540.     { DBASS_2     , "assert"    , EVALP   , NONO , 2    |sysflag  },
  541.     { DBASSA_2    , "asserta"   , EVALP   , NONO , 2    |sysflag  },
  542.     { DBASSZ_2    , "assertz"   , EVALP   , NONO , 2    |sysflag  },
  543.     { DBASS_3     , "assert"    , EVALP   , NONO , 3    |sysflag  },
  544.     { RETRACT_1   , "retract"   , BTEVALP , NONO , 1    |sysflag  },
  545.     { DBRET_2     , "retract"   , BTEVALP , NONO , 2    |sysflag  },
  546.     { RETALL_1    , "retractall", EVALP   , NONO , 1    |sysflag  },
  547.     { ABOL_1       , "abolish"   , EVALP   , NONO , 1    |sysflag  },
  548.     { ABOL_2      , "abolish"   , EVALP   , NONO , 2    |sysflag  },
  549.     { CLAUSE_2    , "clause"    , BTEVALP , NONO , 2    |sysflag  },
  550.     { CLAUSE_3    , "clause"    , BTEVALP , NONO , 3    |sysflag  },
  551.     { CONSULT_1   , "consult"   , EVALP   , NONO , 1    |sysflag  },
  552.     { RECONSULT_1 , "reconsult" , EVALP   , NONO , 1    |sysflag  },
  553.     { LISTALL_0  ,  "listing"   , EVALP   , NONO , 0    |sysflag  },
  554.     { LISTING_1   , "listing"   , EVALP   , NONO , 1    |sysflag  },
  555.  
  556.     { CUT_0       , "!"         , CUTP    , NONO , 0    |sysflag  },
  557.     { FAIL_0      , "fail"      , FAILP   , NONO , 0    |sysflag  },
  558.     { TRUE_0      , "true"      , NORMP   , NONO , 0    |sysflag  },
  559.     { REPEAT_0    , "repeat"    , NORMP   , NONO , 0    |sysflag  },
  560.     { END_0       , "end_of_file", EVALP   , NONO , 0    |sysflag  },
  561.     { HALT_0      , "halt"      , EVALP   , NONO , 0    |sysflag  },
  562.     { EXIT_1      , "exit"      , EVALP   , NONO , 1    |sysflag  },
  563.     { ABORT_0     , "abort"     , EVALP   , NONO , 0    |sysflag  },
  564.     { RESTART_0   , "restart"   , EVALP   , NONO , 0    |sysflag  },
  565.     { CALL_1      , "call"      , NORMP   , NONO , 1    |sysflag  },
  566.     { MAIN_0      , "$main"     , NORMP   , NONO , 0              },
  567.     { SAVE_1      , "save"      , EVALP   , NONO , 1    |sysflag  },
  568.  
  569.     { IS_2        , "is"        , EVALP   , XFXO , 700  |sysflag  },
  570. #if ASSIGN
  571.     { ASSIGN_2    , "##:="        , NORMP   , XFYO , 700  |sysflag  },
  572. #endif
  573.     { LT_2        , "<"         , NORMP   , XFXO , 700  |sysflag  },
  574.     { LE_2        , "=<"        , NORMP   , XFXO , 700  |sysflag  },
  575.     { GT_2        , ">"         , NORMP   , XFXO , 700  |sysflag  },
  576.     { GE_2        , ">="        , NORMP   , XFXO , 700  |sysflag  },
  577.  
  578.     { EQ_2        , "=:="       , NORMP   , XFXO , 700  |sysflag  },
  579.     { NE_2        , "=\\="      , NORMP   , XFXO , 700  |sysflag  },
  580.  
  581.     { PLUS_2      , "+"         , NORMP   , YFXO , 500            },
  582.     { MINUS_2     , "-"         , NORMP   , YFXO , 500            },
  583.     { TIMES_2     , "*"         , NORMP   , YFXO , 400            },
  584.     { DIVIDE_2    , "/"         , NORMP   , YFXO , 400            },
  585.     { MOD_2       , "mod"       , NORMP   , YFXO , 400            },
  586.     { MINUS_1     , "-"         , NORMP   , FYO  , 300            },
  587.  
  588.     { NIL_0       , "[]"        , NORMP   , NONO , 0    |sysflag  },
  589.     { CONS_2      , "."         , NORMP   , XFYO , 300  |sysflag  },
  590.     { CURLY_0     , "{}"        , NORMP   , NONO , 0    |sysflag  },
  591.     { CURLY_1     , "{}"        , NORMP   , NONO , 1    |sysflag  },
  592.     { ARROW_2     , ":-"        , EVALP   , XFXO , 1200 |sysflag  },
  593.     { ARROW_1     , ":-"        , NORMP   , FXO  , 1200 |sysflag  },
  594.     { QUESTION_1  , "?-"        , NORMP   , FXO  , 1200 |sysflag  },
  595.     { SEMI_2      , ";"         , NORMP   , XFYO , 1100 |sysflag  },
  596.     { IMPL_2      , "->"        , NORMP   , XFYO , 1050 |sysflag  },
  597.     { COMMA_2     , ","         , NORMP   , XFYO , 1000 |sysflag  },
  598.     { NOT_1       , "not"       , NORMP   , FYO  , 800  |sysflag  },
  599.     { NOT1_1      , "\\+"       , NORMP   , FYO  , 800  |sysflag  },
  600.     { ISEQ_2      , "="         , NORMP   , XFXO , 700  |sysflag  },
  601.     { ISNEQ_2     , "\\="       , NORMP   , XFXO , 700  |sysflag  },
  602.     { EQUAL_2     , "=="        , EVALP   , XFXO , 700  |sysflag  },
  603.     { NOEQUAL_2   , "\\=="      , EVALP   , XFXO , 700  |sysflag  },
  604.     { TOP_0       , "toplevel"  , NORMP   , NONO , 0              },
  605.     { INIT_0      , "initialize", NORMP   , NONO , 0              },
  606.     { PROMPT_0    , "prompt"    , NORMP   , NONO , 0              },
  607.     { INTERRUPT_0 , "interrupt" , NORMP   , NONO , 0              },
  608.     { ERROR_2     , "error"     , NORMP   , NONO , 2              },
  609.     { UNKNOWN_1   , "unknown"   , NORMP   , NONO , 1              }, 
  610.  
  611.     { STDIN_0     , "stdin"     , NORMP   , NONO , 0              },
  612.     { STDOUT_0    , "stdout"    , NORMP   , NONO , 0              },
  613.     { STDERR_0    , "stderr"    , NORMP   , NONO , 0              },
  614.     { STDTRACE_0  , "stdtrace"  , NORMP   , NONO , 0              },
  615. #if HELP
  616.     { STDHELP_0   , "stdhelp"   , NORMP   , NONO , 0              },
  617. #endif
  618.     { ON_0        , "on"        , NORMP   , NONO , 0              },
  619.     { OFF_0       , "off"       , NORMP   , NONO , 0              },
  620.     { ALL_0       , "all"       , NORMP   , NONO , 0              },
  621.     { USER_0      , "user"      , NORMP   , NONO , 0              },
  622.     { NULL_0      , "null"      , NORMP   , NONO , 0              },
  623.     { FX_0        , "fx"        , NORMP   , NONO , 0              },
  624.     { FY_0        , "fy"        , NORMP   , NONO , 0              },
  625.     { XF_0        , "xf"        , NORMP   , NONO , 0              },
  626.     { YF_0        , "yf"        , NORMP   , NONO , 0              },
  627.     { XFX_0       , "xfx"       , NORMP   , NONO , 0              },
  628.     { XFY_0       , "xfy"       , NORMP   , NONO , 0              },
  629.     { YFX_0       , "yfx"       , NORMP   , NONO , 0              },
  630.     { CALL_0      , "call"      , NORMP   , NONO , 0              },
  631.     { PROVED_0    , "proved"    , NORMP   , NONO , 0              },
  632.     { REDO_0      , "redo"      , NORMP   , NONO , 0              },
  633.     { FAILED_0    , "failed"    , NORMP   , NONO , 0              },
  634.  
  635.     { STATS_0     , "stats"     , EVALP   , NONO , 0    |sysflag  },
  636.     { OP_3        , "op"        , EVALP   , NONO , 3    |sysflag  },
  637.     { DICT_1      , "dict"      , EVALP   , NONO , 1    |sysflag  },
  638.     { SDICT_1     , "sdict"     , EVALP   , NONO , 1    |sysflag  },
  639.     { SYS_1       , "sys"       , EVALP   , NONO , 1    |sysflag  },
  640.     { SORT_2      , "sort1"      , EVALP   , NONO , 2    |sysflag  },
  641.     { SORT0_2     , "sort"     , EVALP   , NONO , 2    |sysflag  },
  642.  
  643.     { EVALUATE_2  , "$evaluate"  , ARITHP  , NONO , 2    |sysflag  },
  644.     { DASSIGN_2    , "$dass"     , EVALP   , NONO , 2    |sysflag  },
  645.     { REDUCE_2     , "$reduce"    , EVALP   , NONO , 2    |sysflag  },
  646.     { ACOMP_1     , "$acomp"     , EVALP   , NONO , 1    |sysflag  },
  647.  
  648.     { MAXINT_0    , "maxint"    , NORMP   , NONO , 0               },
  649.     { MININT_0    , "minint"    , NORMP   , NONO , 0               },
  650.     { MAXAR_0     , "maxarity"  , NORMP   , NONO , 0           },
  651.     { MAXDEP_0    , "maxdepth"  , NORMP   , NONO , 0           },
  652. #if REALARITH
  653.     { E_0          , "e"         , NORMP   , NONO , 0              },
  654.     { PI_0         , "pi"        , NORMP   , NONO , 0              }, 
  655.     { REAL_1       , "real"      , EVALP   , NONO , 1              },
  656.     { EXP_1        , "exp"       , NORMP   , NONO , 1              },
  657.     { LN_1         , "ln"        , NORMP   , NONO , 1              },
  658.     { LOG10_1      , "log10"     , NORMP   , NONO , 1              },
  659.     { SQRT_1       , "sqrt"      , NORMP   , NONO , 1              },
  660.     { SIN_1        , "sin"       , NORMP   , NONO , 1              },
  661.     { COS_1        , "cos"       , NORMP   , NONO , 1              },
  662.     { TAN_1        , "tan"       , NORMP   , NONO , 1              },
  663.     { ASIN_1       , "asin"      , NORMP   , NONO , 1              },
  664.     { ACOS_1       , "acos"      , NORMP   , NONO , 1              },
  665.     { ATAN_1       , "atan"      , NORMP   , NONO , 1              },
  666.     { FLOOR_1      , "floor"     , NORMP   , NONO , 1              },
  667.     { CEIL_1       , "ceil"      , NORMP   , NONO , 1              },
  668.     { POWER_2      , "**"        , NORMP   , XFYO , 350            },
  669.     { ENTIER_1    , "entier"    , NORMP   , NONO , 1              },
  670. #endif
  671.     { LSHIFT_2    , "<<"        , NORMP   , XFYO , 600            },
  672.     { RSHIFT_2    , ">>"        , NORMP   , XFYO , 600            },
  673.     { BITAND_2    , "&"         , NORMP   , XFYO , 650            },
  674.     { BITOR_2     , "\\"        , NORMP   , XFYO , 650            },
  675.     { AND_2        , "&&"        , NORMP   , XFYO , 650            },
  676.     { OR_2         , "\\\\"      , NORMP   , XFYO , 650            },
  677.     { NEG_1        , "/"         , NORMP   , FYO  , 300            },
  678.     { BITNEG_1    , "~"          , NORMP   , FYO , 300              },
  679.     { IDIV_2       , "//"        , NORMP   , YFXO , 400            },
  680.     { ALT_2        , "@<"        , EVALP   , XFXO , 700  |sysflag  },
  681.     { ALE_2        , "@=<"       , EVALP   , XFXO , 700  |sysflag  },
  682.     { AGT_2        , "@>"        , EVALP   , XFXO , 700  |sysflag  },
  683.     { AGE_2        , "@>="       , EVALP   , XFXO , 700  |sysflag  },
  684.     { AEQ_2        , "@="        , EVALP   , XFXO , 700  |sysflag  },
  685.     { ANE_2        , "@\\="      , EVALP   , XFXO , 700  |sysflag  },
  686.     { EVAL_1       , "eval"      , NORMP   , NONO , 1              },
  687.     { QUOTE_1      , "`"         , NORMP   , FYO  , 650            },
  688.     { NL_2        , "\n"        , NORMP   , XFYO , 999            },
  689.     { VERSION_0   , "version"   , EVALP   , NONO , 0   |sysflag   },
  690.     { PRIVATE_1   , "private"   , EVALP   , NONO , 1   |sysflag   },
  691.     { HIDE_1      , "hide"      , EVALP   , NONO , 1   |sysflag   },
  692.     { ENSURE_3    , "ensure"    , EVALP   , NONO , 3   | sysflag  },
  693.     { ANCESTORS_1 , "ancestors" , EVALP   , NONO , 1   | sysflag  },
  694.     { GOTO_1      , "$goto"     , GOTOP   , NONO , 1   | sysflag   },
  695.  
  696.     { OPSYS_1     , "operating_system",EVALP,NONO, 1    |sysflag  },
  697.     { TIMER_1     , "timer"     , EVALP   , NONO , 1    |sysflag  },
  698.     { ARGC_1      , "argc"      , EVALP   , NONO , 1    |sysflag  },
  699.     { ARGV_2      , "argv"      , EVALP   , NONO , 2    |sysflag  },
  700.  
  701. #if !CPM
  702.     { TIME_3      , "time"      , EVALP   , NONO , 3    |sysflag  },
  703.     { DATE_3      , "date"      , EVALP   , NONO , 3    |sysflag  },
  704.     { WEEKDAY_1   , "weekday"   , EVALP   , NONO , 1    |sysflag  },
  705.     { GETENV_2    , "getenv"    , EVALP   , NONO , 2   | sysflag  },
  706. #if !RISCOS
  707.     { PUTENV_2    , "putenv"    , EVALP   , NONO , 2    |sysflag  },
  708. #endif
  709.     { SYSTEM_1    , "system"    , EVALP   , NONO , 1    |sysflag  },
  710. #endif
  711.  
  712. #if HELP
  713.     { HELP_0      , "help"      , EVALP   , NONO , 0   | sysflag  },
  714.     { HELP_1      , "help"      , EVALP   , NONO , 1   | sysflag  },
  715. #endif
  716.  
  717. #if DBASE3
  718.     { OPENDBF_2   , "opendbf"   , EVALP   , NONO , 2   | sysflag  },
  719.     { CREATEDBF_2 , "createdbf" , EVALP   , NONO , 2   | sysflag  },
  720.     { CLOSEDBF_1  , "closedbf"  , EVALP   , NONO , 1   | sysflag  },
  721.     { READDBF_3   , "readdbf"   , BTEVALP , NONO , 3   | sysflag  },
  722.     { WRITEDBF_3  , "writedbf"  , EVALP   , NONO , 3   | sysflag  },
  723.     { SEEKDBF_2   , "seekdbf"   , EVALP   , NONO , 2   | sysflag  },
  724.     { ERASEDBF_2  , "erasedbf"  , EVALP   , NONO , 2   | sysflag  },
  725. #endif
  726.  
  727. #if SYMBOLARITH
  728.     { COLON_2     , ":"         , NORMP   , XFYO , 600     },
  729.     { INL_1       , "inl"       , NORMP   , NONO , 1       },
  730.     { INR_1       , "inr"       , NORMP   , NONO , 1       },
  731.     { SPREAD_2    , "spread"    , NORMP   , NONO , 2       },
  732.     { DECIDE_3    , "decide"    , NORMP   , NONO , 3       },
  733.     { IND_4       , "ind"       , NORMP   , NONO , 4       },
  734.     { INT_EQ_4    , "int_eq"    , NORMP   , NONO , 4       },
  735.     { LISTIND_3   , "list_ind"  , NORMP   , NONO , 3       },
  736.     { LAMBDA_1    , "lambda"    , NORMP   , NONO , 1       },
  737.     { SUBST_3     , "subst"     , NORMP   , NONO , 3       },
  738.     { SUBST_4     , "subst"     , EVALP   , NONO , 4       },
  739.     { RECIND_3    , "rec_ind"   , NORMP   , NONO , 3       },
  740.     { TILDE_0     , "~"         , NORMP   , NONO , 0       },
  741.     { OF_2        , "of"        , NORMP   , YFXO , 250     },
  742.     { SUCC_1      , "s"         , NORMP   , NONO , 1       },
  743.     { PRED_1      , "p"         , NORMP   , NONO , 1       },
  744.     { PIND_3      , "p_ind"     , NORMP   , NONO , 3       },
  745. #endif
  746.  
  747. #if HACKY
  748.     { iCHOICEP_1 , "$$choicep"  , EVALP   , NONO , 1 |sysflag},
  749.     { iHEAPT_1   , "$$heapt"    , EVALP   , NONO , 1 |sysflag},
  750.     { iSTACKT_1  , "$$stackt"   , EVALP   , NONO , 1 |sysflag},
  751.     { iAHEAPT_1  , "$$aheapt"   , EVALP   , NONO , 1 |sysflag},
  752.     { iASTACKT_1 , "$$astackt"  , EVALP   , NONO , 1 |sysflag},
  753.     { iENV_1     , "$$env"      , EVALP   , NONO , 1 |sysflag},
  754.     { iTRAIL_1   , "$$trail"    , EVALP   , NONO , 1 |sysflag},
  755.     { iNROFCALLS_2,"$$nrofcalls", EVALP   , NONO , 2 |sysflag},
  756. #endif
  757.  
  758. #if CPM
  759.     { BDOS_3      , "bdos"      , EVALP   , NONO , 3 |sysflag},
  760.     { PEEK_3      , "peek"      , EVALP   , NONO , 3 |sysflag},
  761.     { POKE_2      , "poke"      , EVALP   , NONO , 2 |sysflag},
  762. #endif
  763.  
  764.     { 0           , "\0"        , 0       , 0    , 0       }
  765.  };
  766.  
  767.  
  768. GLOBAL void InitAtoms(void)
  769. { register int I;
  770.   int Arity,Oprec,Predtype,Optype;
  771.   string Name;
  772.   ATOM A; 
  773.   for(I=0;I<HASHSIZE;I++) HASHTAB[I]=nil_atom; /* ??? */
  774.   INIT=true;
  775.   nextatom(MAXATOMS)=MAXSTRINGS;
  776.   for(I=0;InitT[I].macro;I++)
  777.     { CONSTATOM=InitT[I].macro;
  778.       Name=InitT[I].str; 
  779.       Optype=InitT[I].optype;
  780.       Predtype=InitT[I].predtype;
  781.       Oprec=InitT[I].prec & ~sysflag;
  782.       switch(Optype)
  783.  { case XFXO: case XFYO : case YFXO : Arity=2; break;
  784.           case NONO : Arity=Oprec; Oprec=0; break;
  785.           default: Arity=1; break;
  786.         }
  787.       A=LOOKUP(Name,Arity,true);
  788.       oprec(A)=Oprec; 
  789.       if(InitT[I].prec & sysflag) setsystem(A);
  790.       setoclass(A,Optype); setclass(A,Predtype);
  791.     }
  792.   INIT=false;
  793.   nextatom(ATOMSTOP)=(card)STRINGSTOP;
  794.   setclass(UNBOUNDT,VARP); setsystem(UNBOUNDT);
  795.   setclass(VART,VARP); setsystem(VART);
  796.   setclass(SKELT,VARP); setsystem(SKELT);
  797.   setclass(INTT,VARP); setsystem(INTT);
  798. }
  799.  
  800. #if USER
  801. GLOBAL void InitUAtom(int Phase, int Macro, string Name, int Predtype, 
  802.                       int Optype, int Oprec, int System)
  803. { int Arity;
  804.   ATOM A; 
  805.   /* InitUAtom(0,...) is called at the very beginning
  806.      from  InitUser(0)  and sets  LASTATOM and ATOMHTOP ;
  807.      InitUAtom(1,...) is called from InitUser(1) after
  808.      InitAtoms()  and InitDatabase() 
  809.   */
  810.   if(Phase==0) 
  811.      { inc_atom(LASTATOM); inc_atom(ATOMHTOP); return; }
  812.   INIT=true;
  813.   CONSTATOM=Macro;
  814.   STARTATOM();
  815.   switch(Optype)
  816.        { case XFXO: case XFYO : case YFXO : Arity=2; break;
  817.           case NONO : Arity=Oprec; Oprec=0; break;
  818.           default: Arity=1; break;
  819.         }
  820.   A=LOOKUP(Name,Arity,true);
  821.   oprec(A)=Oprec; 
  822.   if(System) setsystem(A); 
  823.   setoclass(A,Optype); setclass(A,Predtype);
  824.   INIT=false;
  825. }
  826. #endif
  827.  
  828.  
  829. GLOBAL boolean DONAME (void)
  830.   switch(name(A0))
  831.   {
  832.         case INTT:  return UNI(A1,LISTREP(itoa(ival(A0))));
  833. #if LONGARITH
  834.         case LONGT: return UNI(A1,LISTREP(ltoa(longval(A0))));
  835. #endif
  836. #if REALARITH
  837.         case REALT: return UNI(A1,LISTREP(ftoa(realval(A0))));
  838. #endif
  839.         case UNBOUNDT: 
  840.             {
  841.                 register TERM  X;
  842.                 register int C;
  843.                 STARTATOM();
  844.                 X=A1;
  845.                 while(name(X)==CONS_2)
  846.                 { 
  847.                     C=INTVALUE(arg1(X));
  848.                     if(C <=0 || C > 255) ARGERROR();
  849.                     ATOMCHAR(C);
  850.                     X=arg2(X);
  851.                 }
  852.                 TESTATOM(NIL_0,X);
  853.                 ATOMCHAR(0);
  854.                 return UNI(A0,mkatom(LOOKUP(NEWATOM,0,false)));
  855.             }  
  856.         default: CHECKATOM(A0);
  857.                  return UNI(A1,LISTREP(tempcopy(name(A0))));
  858.     }
  859. }
  860.  
  861. GLOBAL void DOOP (void)
  862.     PREC_TYPE P;
  863.     ARITY_TYPE ARITY;
  864.     ATOM  A;
  865.     int F,F1,F2; /* OpType */
  866.     TERM T;
  867.   
  868.     if( (P=INTVALUE(A0)) < 0 || P > MAXPREC) ARGERROR();
  869.     if(name(A2)!=CONS_2) CHECKATOM(A2);
  870.     switch(A=name(A1))
  871.     { 
  872.         case FX_0:   F=FXO ; ARITY=1; break;
  873.         case FY_0:   F=FYO;  ARITY=1; break; 
  874.         case XF_0:   F=XFO;  ARITY=1; break;
  875.         case YF_0:   F=YFO;  ARITY=1; break;
  876.         case XFX_0:  F=XFXO; ARITY=2; break;
  877.         case XFY_0:  F=XFYO; ARITY=2; break; 
  878.         case YFX_0:  F=YFXO; ARITY=2; break; 
  879.         default:     ARGERROR();
  880.     }
  881.     if(P==0) F=NONO;
  882.     do
  883.     {
  884.         if(name(A2)==CONS_2)
  885.         {
  886.             T=arg1(A2); A2=arg2(A2);
  887.             if(name(A2)==NIL_0) A2=nil_term;
  888.         }
  889.         else 
  890.         {
  891.             T=A2; A2=nil_term;
  892.         }
  893.         CHECKATOM(T);
  894.         F1=oclass(LOOKATOM(name(T),-1));
  895.         F2=oclass(LOOKATOM(name(T),-2));
  896.         /* A must be copy to heap, because some infos are global */
  897.         A=copyatom( LOOKATOM(name(T),ARITY) );
  898.         if(system(A) && !aSYSMODE) ERROR(SYSPROCE);
  899.         if(WARNFLAG && P)
  900.         {
  901.           if(oclass(A) !=NONO)
  902.           { ws("WARNING: redeclaration of operator ");
  903.             wq(A);ws("/"); wi(ARITY);ws("\n");
  904.           }
  905.           if( /* infix-postfix-conflict */ 
  906.              ((F==XFXO || F==XFYO || F==YFXO)&&(F1==FXO || F1==FYO)) ||
  907.              ((F==XFO || F==YFO)&&(F2==XFXO || F2==XFYO || F2==YFXO)))
  908.           { ws("WARNING: possibly conflicting infix/postfix ");
  909.             ws("declaration for "); wq(A); ws("\n");
  910.           }
  911.         }
  912.         setoclass(A,(int)F); oprec(A)=P;
  913.     } while(A2 !=nil_term);
  914. }
  915.  
  916.  
  917.